#include "IOCP_Pleafles.h"
#include <QDebug>


IOCP_Pleafles::IOCP_Pleafles(QObject *parent) : QObject(parent)
{
    m_hIOCP = nullptr;
    m_bInitOnce = false;

#ifdef QT_DEBUG
    m_libIOCP.setFileName("IOCP_PleaflesD.dll");
#else
    m_libIOCP.setFileName("IOCP_Pleafles.dll");
#endif
    if(!m_libIOCP.load())
    {
        qCritical()<<"Dll加载失败!";
        return;
    }

    //动态获取函数
    CreateIOCP = (_CreateIOCP)m_libIOCP.resolve("CreateIOCP");
    LoadSocketLib = (_LoadSocketLib)m_libIOCP.resolve("LoadSocketLib");

    __Start = (_Start)m_libIOCP.resolve("Start");
    __Stop = (_Stop)m_libIOCP.resolve("Stop");

    __Send = (_Send)m_libIOCP.resolve("Send");

    __Close = (_Close)m_libIOCP.resolve("Close");
    __ReleaseSocketContext = (_ReleaseSocketContext)m_libIOCP.resolve("ReleaseSocketContext");

    __TraverseSockets = (_TraverseSockets)m_libIOCP.resolve("TraverseSockets");

    __Debug = (_Debug)m_libIOCP.resolve("Debug");

    ReleaseIOCP = (_ReleaseIOCP)m_libIOCP.resolve("ReleaseIOCP");

    GetNoOfProcessors = (_GetNoOfProcessors)m_libIOCP.resolve("GetNoOfProcessors");
    GetLocalIP = (_GetLocalIP)m_libIOCP.resolve("GetLocalIP");

    UnloadSocketLib = (_UnloadSocketLib)m_libIOCP.resolve("UnloadSocketLib");

    __SocketIPPort = (_SocketIPPort)m_libIOCP.resolve("SocketIPPort");

    __SetSocketExtraData = (_SetSocketExtraData)m_libIOCP.resolve("SetSocketExtraData");
    __SocketExtraData = (_SocketExtraData)m_libIOCP.resolve("SocketExtraData");

    SetIOCPSetSocketExtraDataCallback = (_SetIOCPSetSocketExtraDataCallback)m_libIOCP.resolve("SetIOCPSetSocketExtraDataCallback");
    SetIOCPUnsetSocketExtraDataCallback = (_SetIOCPUnsetSocketExtraDataCallback)m_libIOCP.resolve("SetIOCPUnsetSocketExtraDataCallback");
    SetIOCPInitSocketExtraDataCallback = (_SetIOCPInitSocketExtraDataCallback)m_libIOCP.resolve("SetIOCPInitSocketExtraDataCallback");
    SetIOCPReleaseSocketExtraDataCallback = (_SetIOCPReleaseSocketExtraDataCallback)m_libIOCP.resolve("SetIOCPReleaseSocketExtraDataCallback");


    __SetIP = (_SetIP)m_libIOCP.resolve("SetIP");
    __SetPort = (_SetPort)m_libIOCP.resolve("SetPort");

    __SetIOCPFlag = (_SetIOCPFlag)m_libIOCP.resolve("SetIOCPFlag");

    __SetIOCPMessageCallback = (_SetIOCPMessageCallback)m_libIOCP.resolve("SetIOCPMessageCallback");
    __SetIOCPDbgMessageCallback = (_SetIOCPDbgMessageCallback)m_libIOCP.resolve("SetIOCPDbgMessageCallback");
    __SetIOCPAcceptCallback = (_SetIOCPAcceptCallback)m_libIOCP.resolve("SetIOCPAcceptCallback");
    __SetIOCPRecvCallback = (_SetIOCPRecvCallback)m_libIOCP.resolve("SetIOCPRecvCallback");
    __SetIOCPSendCallback = (_SetIOCPSendCallback)m_libIOCP.resolve("SetIOCPSendCallback");
    __SetIOCPCloseCallback = (_SetIOCPCloseCallback)m_libIOCP.resolve("SetIOCPCloseCallback");
    __SetIOCPWatchCallback = (_SetIOCPWatchCallback)m_libIOCP.resolve("SetIOCPWatchCallback");
    __SetIOCPTraverseCallback = (_SetIOCPTraverseCallback)m_libIOCP.resolve("SetIOCPTraverseCallback");


    __SetIOCPCountProperty = (_SetIOCPCountProperty)m_libIOCP.resolve("SetIOCPCountProperty");

    __SetWatchThreadInterval = (_SetWatchThreadInterval)m_libIOCP.resolve("SetWatchThreadInterval");
    __SetSocketTimeoutSecond = (_SetSocketTimeoutSecond)m_libIOCP.resolve("SetSocketTimeoutSecond");

    __SetHeartData = (_SetHeartData)m_libIOCP.resolve("SetHeartData");

    __SetSocketSendAndRecvBufferLength = (_SetSocketSendAndRecvBufferLength)m_libIOCP.resolve("SetSocketSendAndRecvBufferLength");



    if(CreateIOCP == false)
        qCritical()<<"CreateIOCP加载失败!";
    if(LoadSocketLib == false)
        qCritical()<<"LoadSocketLib加载失败!";
    if(__SetIOCPFlag == false)
        qCritical()<<"SetIP加载失败!";
    if(__SetPort == false)
        qCritical()<<"SetPort加载失败!";
    if(__SetIOCPFlag == false)
        qCritical()<<"SetIOCPFlag加载失败!";
    if(__Start == false)
        qCritical()<<"Start加载失败!";
    if(__Stop == false)
        qCritical()<<"Stop加载失败!";
    if(__Send == false)
        qCritical()<<"Send加载失败!";
    if(__Close == false)
        qCritical()<<"Close加载失败!";
    if(__ReleaseSocketContext == false)
        qCritical()<<"ReleaseSocketContext加载失败!";
    if(__SocketIPPort == false)
        qCritical()<<"SocketIPPort加载失败!";
    if(__TraverseSockets == false)
        qCritical()<<"TraverseSockets加载失败!";
    if(__Debug == false)
        qCritical()<<"Debug加载失败!";
    if(ReleaseIOCP == false)
        qCritical()<<"ReleaseIOCP加载失败!";
    if(GetNoOfProcessors == false)
        qCritical()<<"GetNoOfProcessors加载失败!";
    if(GetLocalIP == false)
        qCritical()<<"GetLocalIP 加载失败!";
    if(UnloadSocketLib == false)
        qCritical()<<"UnloadSocketLib 加载失败!";
    if(__SetSocketExtraData == false)
        qCritical()<<"SetSocketExtraData加载失败!";
    if(__SocketExtraData == false)
        qCritical()<<"SocketExtraData加载失败!";

    if(__SetIOCPMessageCallback == false)
        qCritical()<<"SetIOCPMessageCallback加载失败!";
    if(__SetIOCPDbgMessageCallback == false)
        qCritical()<<"SetIOCPDbgMessageCallback加载失败!";
    if(__SetIOCPAcceptCallback == false)
        qCritical()<<"SetIOCPAcceptCallback加载失败!";
    if(__SetIOCPRecvCallback == false)
        qCritical()<<"SetIOCPRecvCallback加载失败!";
    if(__SetIOCPSendCallback == false)
        qCritical()<<"SetIOCPSendCallback加载失败!";
    if(__SetIOCPCloseCallback == false)
        qCritical()<<"SetIOCPCloseCallback加载失败!";
    if(__SetIOCPWatchCallback == false)
        qCritical()<<"SetIOCPWatchCallback加载失败!";
    if(__SetIOCPTraverseCallback == false)
        qCritical()<<"SetIOCPTraverseCallback加载失败!";
    if(SetIOCPSetSocketExtraDataCallback == false)
        qCritical()<<"SetIOCPSetSocketExtraDataCallback加载失败!";
    if(SetIOCPUnsetSocketExtraDataCallback == false)
        qCritical()<<"SetIOCPUnsetSocketExtraDataCallback加载失败!";
    if(SetIOCPInitSocketExtraDataCallback == false)
        qCritical()<<"SetIOCPInitSocketExtraDataCallback加载失败!";
    if(SetIOCPReleaseSocketExtraDataCallback == false)
        qCritical()<<"SetIOCPReleaseSocketExtraDataCallback加载失败!";
    if(__SetIOCPCountProperty == false)
        qCritical()<<"SetIOCPCountProperty加载失败!";
    if(__SetWatchThreadInterval == false)
        qCritical()<<"SetWatchThreadInterval加载失败!";
    if(__SetSocketTimeoutSecond == false)
        qCritical()<<"SetSocketTimeoutSecond加载失败!";
    if(__SetHeartData == false)
        qCritical()<<"SetHeartData加载失败!";
    if(__SetSocketSendAndRecvBufferLength == false)
        qCritical()<<"SetSocketSendAndRecvBufferLength加载失败!";
}

IOCP_Pleafles::~IOCP_Pleafles()
{
    if(m_hIOCP == nullptr)
        return;

    ReleaseIOCP(m_hIOCP);
    UnloadSocketLib(m_hIOCP);

    m_hIOCP = nullptr;
}

bool IOCP_Pleafles::InitOnce()
{
    if(m_bInitOnce == true)
        return true;
    m_bInitOnce = true;

    if(!m_libIOCP.isLoaded())
        return false;
    qDebug() << "IOCPDll载入完毕!";

    if(LoadSocketLib(m_hIOCP) == false)
        return false;
    qDebug() << "SocketLib载入完毕!";

    m_hIOCP = CreateIOCP();
    if(m_hIOCP == nullptr)
        return false;
    qDebug() << "IOCP对象创建完毕!";

    qDebug() << "IOCPInitOnce完毕!";
    return true;
}







//注意:这些都是线程回调函数,不可以直接操作主线程UI!!!
void FUNCTION_CALL_TYPE IOCP_Pleafles::Fn_IOCP_Message_Callback(const char *msg,void *param)
{
    qDebug() << "[IOCP Message]"<<QString::fromLocal8Bit(msg);
    //((IOCP_Pleafles*)param)->Release(msg);
}

void FUNCTION_CALL_TYPE IOCP_Pleafles::Fn_IOCP_Accept_Callback(int socketID,void *pIOCPSocketContext,void*param)
{
    qDebug() << "[IOCP Accept]:new coming:" << pIOCPSocketContext;
    //((IOCP_Pleafles*)param)->Send(socket,"1",2);

    _SocketInfo* pSocketInfo = new _SocketInfo;
    qDebug() << "[IOCP Accept]:new UserData:" << pSocketInfo;

    pSocketInfo->m_SocketContext.nSocketID = socketID;
    pSocketInfo->m_SocketContext.pIOCPSocketContext = pIOCPSocketContext;
    pSocketInfo->m_SocketContext.pSocketInfo = pSocketInfo;

    ((IOCP_Pleafles*)param)->SetSocketExtraData(pSocketInfo, pIOCPSocketContext);

}

void FUNCTION_CALL_TYPE IOCP_Pleafles::Fn_IOCP_Recv_Callback(void*buf,unsigned long buflen,void *pIOCPSocketContext,void*param)
{
    qDebug() << "[IOCP Recv]:comming:" << pIOCPSocketContext << "recived:" << buflen<<(char*)buf;

    _SocketInfo *pSocketInfo = (_SocketInfo*)((IOCP_Pleafles*)param)->SocketExtraData(pIOCPSocketContext);
    qDebug() << "[IOCP Recv]UserData:" << pSocketInfo;

    pSocketInfo->m_baIn.append((char*)buf, buflen);
    //unsigned long ulReaded = 0;           //已经用过的(相当于指针)

    //循环处理粘包,缺包部分(鹰:目前实现的是包足够了才发送,还有一种是 大于最大值也发送 没做.)
    while(1)
    {
        //读长度部分,没有读取过头部(长度)
        if(pSocketInfo->m_ulDataSize == 0)
        {
            if(pSocketInfo->m_dsIn.device()->bytesAvailable() >= sizeof(unsigned long))
            {
                //保存剩下的长度
                quint32 t;
                pSocketInfo->m_dsIn >> t;
                pSocketInfo->m_ulDataSize = t;    //读数据长度

                qDebug() << "头部:" << pSocketInfo->m_ulDataSize;
                //pSocketInfo->m_ulDataSize = ttt;
            }
            else break;
        }

        //读数据部分
        if(pSocketInfo->m_ulDataSize != 0)
        {
            if(pSocketInfo->m_dsIn.device()->bytesAvailable() >= pSocketInfo->m_ulDataSize)
            {
                //qDebug()<<pSocketInfo->m_dsIn.device()->bytesAvailable();

                QByteArray baData(pSocketInfo->m_ulDataSize, Qt::Uninitialized);
                pSocketInfo->m_dsIn.readRawData(baData.data(), pSocketInfo->m_ulDataSize);

                qDebug()<< "[SocketRecieved]数据读取完毕";

                //!!!数据处理!!!
                //pSocketInfo->m_dsIn和pSocketInfo->m_ulDataSize
                //emit ((Server*)param)->s_readyRead(pSocketInfo, baData);

                pSocketInfo->m_ulDataSize = 0;
            }
            else break;
        }
    }

    //释放掉已经用了的数据
    pSocketInfo->m_baIn.remove(0,pSocketInfo->m_dsIn.device()->pos());
    pSocketInfo->m_dsIn.device()->reset();
}

void FUNCTION_CALL_TYPE IOCP_Pleafles::Fn_IOCP_Send_Callback(void*buf, unsigned long buflen, unsigned long bufTransfered, void *pIOCPSocketContext, void*param)
{
    qDebug() << "[Send]" << bufTransfered << "/" << buflen<< (char*)buf;

    return;

    /*  在IOCP核心中已经判断处理
    if(bufTransfered == 0)
    {
        qDebug() << "貌似断开连接?";
        return;
    }
    else if(bufTransfered > buflen)
    {
        qDebug() << "发送过多?";
        return;
    }
    else if (bufTransfered < buflen)
    {
        qDebug() << "继续发送!...";
        ((IOCP_Pleafles*)param)->Send(pIOCPSocketContext, (char*)buf + bufTransfered, buflen - bufTransfered);
        return;
    }
    else
    {
        qDebug() << "发送成功";
        return;
    }*/
}

void FUNCTION_CALL_TYPE IOCP_Pleafles::Fn_IOCP_Close_Callback(int type, void *pIOCPSocketContext, void*param)
{
    qDebug() << "disconnect!" << type;
    delete (_SocketInfo*)(((IOCP_Pleafles*)param)->SocketExtraData(pIOCPSocketContext));
}

bool FUNCTION_CALL_TYPE IOCP_Pleafles::Fn_IOCP_Watch_Callback(void *pIOCPSocketContext, void*param)
{
    qDebug() << "Watch:" << (int)pIOCPSocketContext;
    return true;
}

void FUNCTION_CALL_TYPE IOCP_Pleafles::Fn_IOCP_Traverse_Callback(void *pIOCPSocketContext, int socketID, void *pExtraData, void*param)
{
    qDebug() << "Traverse:"
           << (int)pIOCPSocketContext
          << socketID
         << (int)pExtraData;
}

void* FUNCTION_CALL_TYPE IOCP_Pleafles::Fn_IOCP_SetSocketExtraData_Callback()
{
    _SocketInfo *pSocketInfo = new _SocketInfo;
    qDebug() << "SetSocketExtraData Callback";
    return pSocketInfo;
}

void FUNCTION_CALL_TYPE IOCP_Pleafles::Fn_IOCP_UnsetSocketExtraData_Callback(void *pExtraData)
{
    if(pExtraData != nullptr)
    {
        delete (_SocketInfo*)pExtraData;
        qDebug() << "UnsetSocketExtraData Callback";
    }
    else
        qCritical() << "!UnsetSocketExtraData Callback ERROR!";
}
